var path = require('path');
var fs = require('fs');
var methods = require('methods');

/*  
实现仿MVC式简易路由，路由格式为/controller或者/action/:id等形式
依赖模块：methods  请手动安装该模块
使用该模块方式示例：
var express = require('express');
var routerHelper = require('../utils/routerHelper');
var router = express.Router();
var app = express();
routerHelper.route(router, '/apiControllers');
app.use('/api',router);

Controller写法示例：
第一种(建议)，输出对象式：
  user.js
    exports.users={
        route:'alluser',    //指定路由名，若指定则路由为/路由名，本例中为/alluser
                            //不指定则路由为/控制器输出属性名，本例中为/users
        paramUrl:['','/:id','/type/:id'],   //参数后缀，可以为单个字符串，也可以为一个数组，指定了该参数，则该控制器匹配多个路由
                                            //本例中匹配/alluser,/alluser/:id,/alluser/type/:id
        method:'get',   //指定http方法，不指定则默认使用get，指定为all时匹配所有方法
        filter:function(req, res, next) {next();},  //拦截器,可指定单个方法或多个方法(数组)
        action:function(req, res, next) {           //该控制器执行的方法，该属性必须指定，否则不能成功注册路由
            res.status(200).json({
                id: req.params.id
            });
        }
    };
    exports.delUsers={
        paramUrl:'/:id',
        route:'users',
        method:'delete',
        action:function(req,res,next){
            res.status(200).json({success:true});
        }
    };


第二种(不建议)，输出函数式:
  index.js:
  
    function(req, res, next) {
        res.json({ test: 'test' });
    };
  若使用了该模块注册路由，则该控制器的路由为：
    /index
  适用post、get、delete等等所有http方法

 */

/**
 * @param  {Express} express.Router()
 * @param  {Object} paths (optional) 配置controller文件夹的路径，未设置则使用默认路径
 *                                  请使用相对根目录路径,如controllers放在根目录下，则可定义为'/controllers'或'controllers'
 */
exports.route = function(router, paths) {
    var approot = process.cwd();
    paths = paths || {};
    var ctrlDir = path.join(approot, (paths || '/controllers'));
    //匹配指定文件夹下的js文件
    fs.readdirSync(ctrlDir)
        .filter(function(file) {
            return (file.indexOf('.js') !== -1);
        })
        .forEach(function(file) {            
            var ctrls = require(path.join(ctrlDir, file));
            //如果控制器就只是一个函数，则默认可通过所有方法访问该模块路由，路由为 “/文件名”
            if (typeof ctrls == 'function') {
                var fileName = path.basename(file, path.extname(file));  
                router.all('/' + fileName, ctrls);
            } else {
                for (var item in ctrls) {
                    var ctrl = ctrls[item];
                    if (ctrl.action) {
                        //未指定method默认为get
                        var method = (ctrl.method || 'get').toLowerCase();
                        var routeName = ctrl.route || item; //路由命名，如果有指定路由名则使用路由名，否则使用属性名
                        var action = [ctrl.filter || [], ctrl.action];
                        //如果指定了路由参数，则将路由参数加入
                        var paramUrl = ctrl.paramUrl || '';
                        //如果参数是字符串，将其转换为数组
                        var paramUrlArray = (Array.isArray(paramUrl)) ? paramUrl : [paramUrl];
                        //注册路由
                        for (var i = 0; i < paramUrlArray.length; i++) {
                            var routeMethod = (method === 'all' || methods.indexOf(method) >= 0) ? method : null;
                            if (routeMethod) {
                                router[method].apply(router, ['/' + routeName + paramUrlArray[i]].concat(action));
                            }
                        }
                    }
                }
            }
        });

    return router;
};
